package com.milo.coding.lambda;

import com.sun.xml.internal.ws.commons.xmlutil.Converter;

import java.util.*;

/**
 * @Auther milo
 * @Description
 * @Date 2021-01-17 14:03
 */
public class LambdaTest {

    public static void main(String[] args) {
        test1();

        test2();
        test3();
    }

    // 静态方法引用
    private static void test3() {
        //格式：Classname :: staticMethodName  和静态方法调用相比，只是把 . 换为 ::
        //String::valueOf   // 等价于lambda表达式 (s) -> String.valueOf(s)
        //Math::pow       //等价于lambda表达式  (x, y) -> Math.pow(x, y);
    }

    /**
     * @Author milo
     * @Date 2021-01-17 14:33:58
     * @Description 变量作用域
     */
    private static void test2() {
        int num = 0;
        Runnable runnable = () -> {
            System.out.println(num); // 与匿名函数同理  lambda 表达式的局部变量可以不用声明为 final，但是必须不可被后面的代码修改（即隐性的具有 final 的语义）
//            num = 1; //ambda 表达式只能引用final 类型的外层局部变量，就是说不能在 lambda 内部修改定义在域外的局部变量，否则会编译错误
        };
        //报错信息：Local variable num defined in an enclosing scope must be final or effectively final
        //在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
        String first = "";
        Comparator<String> comparator = (first1, second) -> Integer.compare(first.length(), second.length());  //first1换成first编译会出错
    }

    /**
     * @Author milo
     * @Date 2021-01-17 14:08:43
     * @Description 匿名内部类
     */
    private static void test1() {
        // Runnable
        // @FunctionalInterface 注解表明该接口只有一个需要实现的函数，修饰函数式接口
        // 如果有该注解修饰，该接口不能在新增函数
        Runnable run = new Runnable() {
            @Override
            public void run() {
                System.out.println("常规写法");
            }
        };

        Runnable runnable = () -> {
            System.out.println("新写法：lambda");
        }; // 如果方法体只有一行代码，{} 可以省略

        new Thread(run).start();
        new Thread(runnable).start();

        new Thread(() -> System.out.println("lambda...")).start();

        // Comparator
        Comparator<String> com = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        };

        TreeSet<String> tree = new TreeSet<>(com);
        TreeSet<String> treeSet1 = new TreeSet<>((o1, o2) -> o1.length() - o2.length());
    }

    // 匿名函数
    public static void test() {
        // 1. 不需要参数,返回值为 5  {}只有一行代码，可以省略
        // () -> 5;

        // 2. 接收一个参数(数字类型),返回其2倍的值，()只有一个参数可以省略
        // x -> 2 * x

        // 3. 接受2个参数(数字),并返回他们的差值
        // (x, y) -> x – y

        // 4. 接收2个int型整数,返回他们的和
        // (int x, int y) -> x + y

        // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
        // (String s) -> System.out.print(s)
    }

}
